package com.pactera.madp.cp.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.data.tenant.TenantContextHolder;
import com.pactera.madp.cp.api.dto.product.ProductAddDto;
import com.pactera.madp.cp.api.dto.product.ProductQueryDto;
import com.pactera.madp.cp.api.dto.product.ProductUpdateDto;
import com.pactera.madp.cp.api.entity.BaseEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeDepartmentEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeEntity;
import com.pactera.madp.cp.api.entity.product.ProductEntity;
import com.pactera.madp.cp.api.entity.product.ProductGroupDepartmentEntity;
import com.pactera.madp.cp.api.entity.product.ProductGroupEntity;
import com.pactera.madp.cp.api.vo.product.ProductVO;
import com.pactera.madp.cp.common.constant.Constant;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.product.ProductMapper;
import com.pactera.madp.cp.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 产品管理服务实现类
 *
 * @author kedongZhang
 * @date 2021/5/26 10:28
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper,ProductEntity> implements ProductService {

    @Autowired
    ProductGroupService productGroupService;
    @Autowired
    ProductGroupDepartmentService productGroupDepartmentService;
    @Autowired
    IWorkDeptService workDeptService;
    @Autowired
    IWorkEmployeeDepartmentService workEmployeeDepartmentService;
    @Autowired
    IWorkEmployeeService workEmployeeService;

    /**
     * 新增产品
     */
    @Override
    public R saveProduct(ProductAddDto dto) {
        //校验产品名是否重复
        ProductEntity checkNameEntity = this.getOne(Wrappers.<ProductEntity>query().lambda()
                .eq(ProductEntity::getName, dto.getName())
                .eq(ProductEntity::getCorpId,CorpContextHolder.getCorpId()));
        if (checkNameEntity != null) {
            return R.failed(Boolean.FALSE,"新增失败，产品名称已存在");
        }
        if (dto.getEndTime().isBefore(dto.getStartTime())) {
            return R.failed(Boolean.FALSE,"新增失败，结束日期必须在开始日期之后");
        }
        //产品类别下拉框此处排除精选,因为查询精选产品返回结果：只匹配精选标识字段进行查询，精选与各个产品并无关联关系，参考接口/product/page
        ProductGroupEntity groupEntity = productGroupService.getById(dto.getGroupId());
        if (groupEntity.getName().equals("精选")) {
            return R.failed(Boolean.FALSE,"不可选择以下产品分类：精选");
        }

        ProductEntity productEntity = new ProductEntity();
        BeanUtils.copyProperties(dto,productEntity);
        productEntity.setCreateTime(LocalDateTime.now());
        productEntity.setEndTime(dto.getEndTime().withHour(23).withMinute(59).withSecond(59));
        productEntity.setCorpId(AccountService.getCorpId());
        productEntity.setTenantId(AccountService.getTenantId());
        return R.ok(this.save(productEntity));
    }

    /**
     *  分页查询  产品
     */
    @Override
    public R getProductPage(Page page, ProductQueryDto dto) {
        QueryWrapper<ProductEntity> queryWrapper = new QueryWrapper<>();
        List<Object> groupIds = new ArrayList<>();
        List<Integer> deptIds;
        boolean isGroup = false;
        boolean isSession = false;
        boolean isDepartment = false;
        // 首先判断是否groupId是否为空 ，在判断是否为精选，来设置是否是分类查询
        if (dto.getGroupId() != null) {
            ProductGroupEntity productGroupEntity = productGroupService.getById(dto.getGroupId());
            isGroup = true;
            if (productGroupEntity.getName().equals("精选")) {
                isSession = true;
                isGroup = false;
            }
        }
        // 判断部门条件是否为空， 是否是分类查询
        if (dto.getDepartment() != null) {
            isGroup = false;
            isDepartment = true;
            deptIds = workDeptService.getAllChilds(dto.getDepartment());
            groupIds = productGroupDepartmentService.getBaseMapper().selectObjs(Wrappers.<ProductGroupDepartmentEntity>query().select("group_id").in("dept_id", deptIds));
        }
        // 过滤是否是分类查询
        if (isGroup) groupIds.add(dto.getGroupId());

        if (isSession) {
            queryWrapper.lambda().eq(ProductEntity::getSelection, Constant.PRODUCT_SELECTION_ON);

            //且groupIds不为空意味着情况应该是部门查询，或分类查询， 为空意味着是只可能是精选分类或者无条件查询
            if (isDepartment || isGroup) {
                if (groupIds.size() == 0) groupIds.add(null);
                queryWrapper.lambda().in(ProductEntity::getGroupId, groupIds);
            }
            //若不为空则追加查询条件
            if (StrUtil.isNotBlank(dto.getName())) queryWrapper.lambda().like(ProductEntity::getName,dto.getName());
            if (dto.getStatus() != null) queryWrapper.lambda().eq(ProductEntity::getStatus,dto.getStatus());

            queryWrapper.lambda().eq(ProductEntity::getCorpId,CorpContextHolder.getCorpId())
                .last("order by sort asc, create_time desc");
            IPage iPage = this.page(page, queryWrapper);
            return R.ok(iPage);
        }
        if (isDepartment || isGroup) {
            if (groupIds.size() == 0) groupIds.add(null);
            dto.setGroupIds(groupIds);
        }
        List<ProductVO> list = this.getProductByquery(page, dto).getRecords();
        Collections.sort(list, new Comparator<ProductVO>() {
            @Override
            public int compare(ProductVO o1, ProductVO o2) {
                return o2.getId() - o1.getId();
            }
        });
        page.setRecords(list);
        return R.ok(page);
    }

    /**
     * 编辑产品
     */
    @Override
    public R updateProduct(ProductUpdateDto dto) {
        //校验产品名是否重复
        ProductEntity checkNameEntity = this.getOne(Wrappers.<ProductEntity>query().lambda()
                .eq(ProductEntity::getName, dto.getName())
                .ne(ProductEntity::getId,dto.getId()));
        if (checkNameEntity != null) {
            return R.failed(Boolean.FALSE,"编辑失败，产品名称已存在");
        }
        if (dto.getEndTime().isBefore(dto.getStartTime())) {
            return R.failed(Boolean.FALSE,"编辑失败，结束日期必须在开始日期之后");
        }

        //产品类别下拉框此处排除精选,因为查询精选产品返回结果：只匹配精选标识字段进行查询，精选与各个产品并无关联关系，参考接口/product/page
        ProductGroupEntity groupEntity = productGroupService.getById(dto.getGroupId());
        if (groupEntity.getName().equals("精选")) {
            return R.failed(Boolean.FALSE,"不可选择以下产品分类：精选");
        }

        ProductEntity productEntity = new ProductEntity();
        BeanUtils.copyProperties(dto,productEntity);
        productEntity.setUpdateTime(LocalDateTime.now());
        productEntity.setEndTime(dto.getEndTime().withHour(23).withMinute(59).withSecond(59));
        return R.ok(this.updateById(productEntity));
    }

    /**
     *   根据分类id 获取获取上架产品列表
     */
    @Override
    public R getPublishedProductListByGroupId(Integer groupId) {
        //如果分类为：精选，则直接返回精选标识为开启状态的产品数据
        ProductGroupEntity productGroupEntity = productGroupService.getById(groupId);
        if(productGroupEntity == null){
            return R.failed("没有查到对应的产品分类");
        }
        if (productGroupEntity.getName().equals("精选")) {
            return R.ok(this.list(Wrappers.<ProductEntity>lambdaQuery()
                    .eq(ProductEntity::getSelection,Constant.PRODUCT_SELECTION_ON)
                    .eq(ProductEntity::getStatus,Constant.PRODUCT_STATUS_PUBLISH_ON)
                    .eq(ProductEntity::getCorpId,AccountService.getCorpId())
                    .eq(ProductEntity::getTenantId,AccountService.getTenantId())
                    .last("order by sort asc, create_time desc")));
        }
        return R.ok(this.list(Wrappers.<ProductEntity>query().lambda()
                .eq(ProductEntity::getGroupId,groupId)
                .eq(ProductEntity::getStatus,Constant.PRODUCT_STATUS_PUBLISH_ON)
                .eq(ProductEntity::getCorpId,AccountService.getCorpId())
                .eq(ProductEntity::getTenantId,AccountService.getTenantId())
                .last("order by sort asc, create_time desc")));
    }

    /**
     *   开启或 关闭  产品精选
     */
    @Override
    public R selectProduct(Integer productId) {
        //获取当前产品精选标识状态
        ProductEntity product = this.getById(productId);
        if (product == null) {
            return R.failed("该产品不存在");
        }
        if (Constant.PRODUCT_SELECTION_ON.equals(product.getSelection())) {
            product.setSelection(Constant.PRODUCT_STATUS_PUBLISH_OFF);
            return R.ok(this.updateById(product),"关闭精选成功");
        } else if (Constant.PRODUCT_SELECTION_OFF.equals(product.getSelection())) {
            product.setSelection(Constant.PRODUCT_STATUS_PUBLISH_ON);
            return R.ok(this.updateById(product),"开启精选成功");
        } else {
            return R.failed(Boolean.FALSE,"开启/关闭精选发生异常");
        }
    }

    /**
     *    侧边栏分页查询产品
     * @param page
     * @param dto
     * @return
     */
    @Override
    public R getSidebarProductPage(String wxUserId, Page page, ProductQueryDto dto) {
        Integer corpId = CorpContextHolder.getCorpId();
        Integer employeeId = workEmployeeService.getObj(Wrappers.<WorkEmployeeEntity>query().select("id").eq("wx_user_id", wxUserId).eq("corp_id", corpId), o -> Integer.parseInt(o.toString()));
        List<Object> myGroupIds = new ArrayList<>();
        List<Integer> myDeptIds = getAdminDeptId(employeeId);
        if (myDeptIds.size() != 0) {
            myGroupIds = productGroupDepartmentService.listObjs(Wrappers.<ProductGroupDepartmentEntity>query().select("group_id").in("dept_id", myDeptIds)).stream().map(m -> (Integer) m).collect(Collectors.toList());
        }
        List<Object> myGroupIds2 = productGroupService.listObjs(Wrappers.<ProductGroupEntity>query().eq("corp_id", corpId).eq("visible_range", 1));
        myGroupIds.addAll(myGroupIds2);
        if (myGroupIds.size() == 0) myGroupIds.add(null);

        dto.setGroupIds(myGroupIds);
        boolean isSelection = false;

        if (dto.getGroupId() != null) {
            String groupName = productGroupService.getObj(Wrappers.<ProductGroupEntity>query().select("name").eq("id", dto.getGroupId()), o -> o.toString());
            //精选则代表查询所有分类精选  另一种则是单分类查询
            if (groupName.equals("精选")) {
                isSelection = true;
                dto.setGroupId(null);
            }
        } else {
            isSelection = true;
        }
        long l = new Date().getTime() / 1000;
        IPage<List<ProductVO>> iPage = baseMapper.getSidebarProductPage(page, dto, isSelection, l);
        return R.ok(iPage);
    }

    /**
     *   根据分类id 获取获取上架产品列表
     */
    @Override
    public R getSidebarPublishedProductListByGroupId(Page page,Integer groupId) {
        Page<ProductEntity> req = new Page<>();
        req.setCurrent(page.getCurrent());
        req.setSize(page.getSize());
        //如果分类为：精选，则直接返回精选标识为开启状态的产品数据
        ProductGroupEntity productGroupEntity = productGroupService.getById(groupId);
        if(productGroupEntity == null){
            return R.failed("没有查到对应的产品分类");
        }
        IPage<ProductEntity> page2=null;
        if (productGroupEntity.getName().equals("精选")) {
             page2 = this.page(req, Wrappers.<ProductEntity>lambdaQuery()
                    .eq(ProductEntity::getSelection, Constant.PRODUCT_SELECTION_ON)
                    .eq(ProductEntity::getStatus, Constant.PRODUCT_STATUS_PUBLISH_ON)
                    .eq(ProductEntity::getCorpId, CorpContextHolder.getCorpId())
                    .eq(ProductEntity::getTenantId, TenantContextHolder.getTenantId())
                    .ge(ProductEntity::getEndTime, new Date())
                    .orderByAsc(ProductEntity::getSort)
                    .orderByDesc(BaseEntity::getCreateTime)
            );
        }else {
             page2 = this.page(req, Wrappers.<ProductEntity>query().lambda()
                    .eq(ProductEntity::getGroupId, groupId)
                    .eq(ProductEntity::getStatus, Constant.PRODUCT_STATUS_PUBLISH_ON)
                    .eq(ProductEntity::getCorpId, CorpContextHolder.getCorpId())
                    .eq(ProductEntity::getTenantId, TenantContextHolder.getTenantId())
                    .ge(ProductEntity::getEndTime, new Date())
                    .orderByAsc(ProductEntity::getSort)
                    .orderByDesc(BaseEntity::getCreateTime)
            );
        }
        List<ProductVO> collect = page2.getRecords().stream().map(entity -> {
            ProductVO productVO = new ProductVO();
            BeanUtils.copyProperties(entity, productVO);
            ProductGroupEntity one = productGroupService.getOne(Wrappers.<ProductGroupEntity>lambdaQuery().eq(ProductGroupEntity::getId, entity.getGroupId()));
            if (one != null) {
                productVO.setGroupName(one.getName());
            }
            return productVO;
        }).collect(Collectors.toList());
        page.setRecords(collect);
        page.setTotal(page2.getTotal());
        return R.ok(page);

}


    /**
     * 分页查询产品信息
     *
     * @param page
     * @param dto
     * @return
     */
    public IPage getProductByquery(Page page, ProductQueryDto dto) {
        Integer corpId = AccountService.getCorpId();
        int tenantId = AccountService.getTenantId();
        return baseMapper.getProductPage(page,dto,corpId,tenantId);
    }


    public List<Integer> getAdminDeptId(Integer userId) {
        // 查询员工所属的部门 id 列表
        List<Integer> idList = workEmployeeDepartmentService.lambdaQuery()
                .select(WorkEmployeeDepartmentEntity::getDepartmentId)
                .eq(WorkEmployeeDepartmentEntity::getEmployeeId, userId)
                .list()
                .stream()
                .map(WorkEmployeeDepartmentEntity::getDepartmentId)
                .collect(Collectors.toList());

        // 查询部门及子部门 id 列表
        ArrayList<Integer> childs = new ArrayList<>();
        idList.forEach(f -> {
            List<Integer> allChilds = workDeptService.getAllChilds(f);
            childs.addAll(allChilds);
        });
        List<Integer> myList = childs.stream().distinct().collect(Collectors.toList());
        // 部门及子部门 id 列表
        return myList;
    }


}
